package fr.asip.cps3.exemple.modele.traitements.util;

import iaik.pkcs.pkcs11.wrapper.Functions;
import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;

import java.awt.Color;
import java.util.Iterator;
import java.util.Vector;

import org.apache.log4j.Logger;

import fr.asip.cps3.exemple.modele.Application;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionProgrammeExemple;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionTraitement;
import fr.asip.cps3.exemple.modele.resultats.Resultat;
import fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.objets.RechercheObjets;
import fr.asip.cps3.exemple.vues.dialogs.SaisieCodeNbEssais;
import fr.asip.cps3.exemple.vues.dialogs.SaisieRecyclage;

/**
 * Classe utilitaire pour les traitements PKCS#11
 *
 */
public class TraitementsUtil {

	/**
	 * Le loggeur
	 */
	private static Logger log = Logger.getLogger(TraitementsUtil.class);

	public static final long AUCUN_CODE_RETOUR = -1L;
	
	public static final int TYPE_OBJET_CERTIFICAT = 1;
	public static final int TYPE_OBJET_CLE_PUBLIQUE = 2;
	public static final int TYPE_OBJET_CLE_PRIVE = 3;
	public static final int TYPE_OBJET_DONNEES_APPLICATIVES = 4;
	
	public static final int TYPE_ACTION_RETRAIT_CARTE = 1;
	public static final int TYPE_ACTION_INSERTION_CARTE = 2;
	public static final int TYPE_ACTION_RETRAIT_LECTEUR = 3;
	public static final int TYPE_ACTION_CONNEXION_LECTEUR = 4;
	
	// tableau des caractères hexadecimaux
	private static char[] caracteresHexa = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f'};
	
    // tableau de traduction des caractères de 0 jusqu'à f
    private static byte[] nibbleCorrespondant = new byte['f' + 1];

    // contruction du tableau de traduction des caractères
    static
    {
	    // on considère uniquement les caractère de 0..9, de A..F, et de a..f
	    for(int i = 0; i <= 'f'; i++)
	    	nibbleCorrespondant[i] = -1;

	    for(int i = '0'; i <= '9'; i++)
	    	nibbleCorrespondant[i] = (byte) (i-'0');
	    
	    for(int i = 'A'; i <= 'F'; i++)
	    	nibbleCorrespondant[i] = (byte) (i-'A'+10);
	    
	    for(int i = 'a'; i <= 'f'; i++)
	    	nibbleCorrespondant[i] = (byte) (i-'a'+10);

    }
	
	/**
	 * Formate un tableau d'octets sous forme de chaîne de caractères
	 * @param octets Tableau d'octets à formater
	 * @param base Base pour la présentation (exemple base 16 pour avoir des lignes de 16 octets)
	 * @return Tableau d'octets sous forme de chaîne de caractère
	 */
	public static String getHexadecimal(byte[] octets, Integer base) {
		
		if(octets != null) {
			
			StringBuffer sb = new StringBuffer(octets.length*2);
			int iterateurOctect = 0;
			for(int i=0; i<octets.length; i++)
			{
				
				// caractère du nibble fort
				sb.append(caracteresHexa[(octets[i] & 0xf0) >>> 4]);
				
				// caractère du nibble faible
				sb.append(caracteresHexa [octets[i] & 0x0f]);
				
				// Si un formatage en base est demandé
				if(base != null) {
					
					iterateurOctect++;
					
					// saut de ligne
					if(iterateurOctect == base) {
						sb.append("\n");
			        	iterateurOctect = 0;
					} 
					
					// ajout d'espace
					else
						sb.append(" ");
					
				}
			}
			
			return sb.toString();
		
		}
		return null;
	}
	
	/**
	 * Re-formate un tableau d'octets dans son format inital
	 * @param octetsString Tableau d'octets sous forme de chaîne de caractères
	 * @return Le tableau d'octets sans formatage
	 * @throw IllegalArgumentException
	 */
	public static byte[] getOctetsSansFormatage(String octetsString) throws IllegalArgumentException {
		
		if(octetsString != null) {
		
			// On enlève les ajouts fait lors du formatage
			octetsString = octetsString.replaceAll("\n", "");
			octetsString = octetsString.replaceAll(" ", "");

			int longueurOctetsString = octetsString.length();

	        if ((longueurOctetsString & 0x1 ) != 0 )
	        	throw new IllegalArgumentException("getOctetsSansFormatage nécessite une nombre paire de caractères hexadécimaux");

	        byte[] octets = new byte[longueurOctetsString/2];

	        for(int i = 0, j = 0; i < longueurOctetsString; i += 2, j++)
	        {
	            int high = charToNibble(octetsString.charAt(i));
	            int low = charToNibble(octetsString.charAt(i+1));
	            
	            octets[j] = (byte) ((high << 4) | low);
	        }
	        return octets;
	
		}
		
		return null;
	}
	

	/**
	 * Converti un caractère en nibble lui correspondant en utilisant le tableau de traduction des caractères
	 * @param c caractère à convertir (0-9 a-f A-F, pas d'espace, pas de signe (+ ou -)
	 * @return Entier correspondant (de 0 à 15)
	 * @throws IllegalArgumentException
	 */
	private static int charToNibble(char c) throws IllegalArgumentException {
		
		if(c > 'f') 
		    throw new IllegalArgumentException("Caractère hexadécimal invalide: " + c); 
		
		int nibble = nibbleCorrespondant[ c ];
		if(nibble < 0 )
		    throw new IllegalArgumentException("Caractère hexadécimal invalide: " + c);
		
		return nibble;
		
	}
    
    /**
     * Recupère le nom de l'algorithme
     * @param algo Algorithme
     * @return Nom de l'algorithme
     */
	public static String getNomAlgo(long algo) {
		
		if(algo == PKCS11Constants.CKM_RSA_PKCS_KEY_PAIR_GEN)
			return PKCS11Constants.NAME_CKM_RSA_PKCS_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_RSA_PKCS)
			return PKCS11Constants.NAME_CKM_RSA_PKCS;
		else if(algo == PKCS11Constants.CKM_RSA_9796)
			return PKCS11Constants.NAME_CKM_RSA_9796;
		else if(algo == PKCS11Constants.CKM_RSA_X_509)
			return PKCS11Constants.NAME_CKM_RSA_X_509;
		else if(algo == PKCS11Constants.CKM_MD2_RSA_PKCS)
			return PKCS11Constants.NAME_CKM_MD2_RSA_PKCS;
		else if(algo == PKCS11Constants.CKM_MD5_RSA_PKCS)
			return PKCS11Constants.NAME_CKM_MD5_RSA_PKCS;
		else if(algo == PKCS11Constants.CKM_SHA1_RSA_PKCS)
			return PKCS11Constants.NAME_CKM_SHA1_RSA_PKCS;
		else if(algo == PKCS11Constants.CKM_RIPEMD128_RSA_PKCS)
			return PKCS11Constants.NAME_CKM_RIPEMD128_RSA_PKCS;
		else if(algo == PKCS11Constants.CKM_RIPEMD160_RSA_PKCS)
			return PKCS11Constants.NAME_CKM_RIPEMD160_RSA_PKCS;
		else if(algo == PKCS11Constants.CKM_RSA_PKCS_OAEP)
			return PKCS11Constants.NAME_CKM_RSA_PKCS_OAEP;
		else if(algo == PKCS11Constants.CKM_RSA_X9_31_KEY_PAIR_GEN)
			return PKCS11Constants.NAME_CKM_RSA_X9_31_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_RSA_X9_31)
			return PKCS11Constants.NAME_CKM_RSA_X9_31;
		else if(algo == PKCS11Constants.CKM_SHA1_RSA_X9_31)
			return PKCS11Constants.NAME_CKM_SHA1_RSA_X9_31;
		else if(algo == PKCS11Constants.CKM_RSA_PKCS_PSS)
			return PKCS11Constants.NAME_CKM_RSA_PKCS_PSS;
		else if(algo == PKCS11Constants.CKM_SHA1_RSA_PKCS_PSS)
			return PKCS11Constants.NAME_CKM_SHA1_RSA_PKCS_PSS;
		else if(algo == PKCS11Constants.CKM_DSA_KEY_PAIR_GEN)
			return PKCS11Constants.NAME_CKM_DSA_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_DSA)
			return PKCS11Constants.NAME_CKM_DSA;
		else if(algo == PKCS11Constants.CKM_DSA_SHA1)
			return PKCS11Constants.NAME_CKM_DSA_SHA1;
		else if(algo == PKCS11Constants.CKM_DH_PKCS_KEY_PAIR_GEN)
			return PKCS11Constants.NAME_CKM_DH_PKCS_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_DH_PKCS_DERIVE)
			return PKCS11Constants.NAME_CKM_DH_PKCS_DERIVE;
		else if(algo == PKCS11Constants.CKM_X9_42_DH_KEY_PAIR_GEN)
			return PKCS11Constants.NAME_CKM_X9_42_DH_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_X9_42_DH_DERIVE)
			return PKCS11Constants.NAME_CKM_X9_42_DH_DERIVE;
		else if(algo == PKCS11Constants.CKM_X9_42_DH_HYBRID_DERIVE)
			return PKCS11Constants.NAME_CKM_X9_42_DH_HYBRID_DERIVE;
		else if(algo == PKCS11Constants.CKM_X9_42_MQV_DERIVE)
			return PKCS11Constants.NAME_CKM_X9_42_MQV_DERIVE;
		else if(algo == PKCS11Constants.CKM_RC2_KEY_GEN)
			return PKCS11Constants.NAME_CKM_RC2_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_RC2_ECB)
			return PKCS11Constants.NAME_CKM_RC2_ECB;
		else if(algo == PKCS11Constants.CKM_RC2_CBC)
			return PKCS11Constants.NAME_CKM_RC2_CBC;
		else if(algo == PKCS11Constants.CKM_RC2_MAC)
			return PKCS11Constants.NAME_CKM_RC2_MAC;
		else if(algo == PKCS11Constants.CKM_RC2_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_RC2_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_RC2_CBC_PAD)
			return PKCS11Constants.NAME_CKM_RC2_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_RC4_KEY_GEN)
			return PKCS11Constants.NAME_CKM_RC4_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_RC4)
			return PKCS11Constants.NAME_CKM_RC4;
		else if(algo == PKCS11Constants.CKM_DES_KEY_GEN)
			return PKCS11Constants.NAME_CKM_DES_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_DES_ECB)
			return PKCS11Constants.NAME_CKM_DES_ECB;
		else if(algo == PKCS11Constants.CKM_DES_CBC)
			return PKCS11Constants.NAME_CKM_DES_CBC;
		else if(algo == PKCS11Constants.CKM_DES_MAC)
			return PKCS11Constants.NAME_CKM_DES_MAC;
		else if(algo == PKCS11Constants.CKM_DES_MAC_GENERAL) 
			return PKCS11Constants.NAME_CKM_DES_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_DES_CBC_PAD)
			return PKCS11Constants.NAME_CKM_DES_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_DES2_KEY_GEN)
			return PKCS11Constants.NAME_CKM_DES2_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_DES3_KEY_GEN)
			return PKCS11Constants.NAME_CKM_DES3_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_DES3_ECB)
			return PKCS11Constants.NAME_CKM_DES3_ECB;
		else if(algo == PKCS11Constants.CKM_DES3_CBC) 
			return PKCS11Constants.NAME_CKM_DES3_CBC;
		else if(algo == PKCS11Constants.CKM_DES3_MAC)
				return PKCS11Constants.NAME_CKM_DES3_MAC;
		else if(algo == PKCS11Constants.CKM_DES3_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_DES3_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_DES3_CBC_PAD)
			return PKCS11Constants.NAME_CKM_DES3_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_CDMF_KEY_GEN)
			return PKCS11Constants.NAME_CKM_CDMF_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_CDMF_ECB)
			return PKCS11Constants.NAME_CKM_CDMF_ECB;
		else if(algo == PKCS11Constants.CKM_CDMF_CBC)
			return PKCS11Constants.NAME_CKM_CDMF_CBC;
		else if(algo == PKCS11Constants.CKM_CDMF_MAC)
			return PKCS11Constants.NAME_CKM_CDMF_MAC;
		else if(algo == PKCS11Constants.CKM_CDMF_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_CDMF_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_CDMF_CBC_PAD)
			return PKCS11Constants.NAME_CKM_CDMF_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_MD2)
			return PKCS11Constants.NAME_CKM_MD2;
		else if(algo == PKCS11Constants.CKM_MD2_HMAC)
			return PKCS11Constants.NAME_CKM_MD2_HMAC;
		else if(algo == PKCS11Constants.CKM_MD2_HMAC_GENERAL)
			return PKCS11Constants.NAME_CKM_MD2_HMAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_MD5)
			return PKCS11Constants.NAME_CKM_MD5;
		else if(algo == PKCS11Constants.CKM_MD5_HMAC)
			return PKCS11Constants.NAME_CKM_MD5_HMAC;
		else if(algo == PKCS11Constants.CKM_MD5_HMAC_GENERAL)
			return PKCS11Constants.NAME_CKM_MD5_HMAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_SHA_1)
			return PKCS11Constants.NAME_CKM_SHA_1;
		else if(algo == PKCS11Constants.CKM_SHA_1_HMAC)
			return PKCS11Constants.NAME_CKM_SHA_1_HMAC;
		else if(algo == PKCS11Constants.CKM_SHA_1_HMAC_GENERAL)
			return PKCS11Constants.NAME_CKM_SHA_1_HMAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_RIPEMD128)
			return PKCS11Constants.NAME_CKM_RIPEMD128;
		else if(algo == PKCS11Constants.CKM_RIPEMD128_HMAC)
			return PKCS11Constants.NAME_CKM_RIPEMD128_HMAC;
		else if(algo == PKCS11Constants.CKM_RIPEMD128_HMAC_GENERAL)
			return PKCS11Constants.NAME_CKM_RIPEMD128_HMAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_RIPEMD160)
			return PKCS11Constants.NAME_CKM_RIPEMD160;
		else if(algo == PKCS11Constants.CKM_RIPEMD160_HMAC)
			return PKCS11Constants.NAME_CKM_RIPEMD160_HMAC;
		else if(algo == PKCS11Constants.CKM_RIPEMD160_HMAC_GENERAL)
			return PKCS11Constants.NAME_CKM_RIPEMD160_HMAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_CAST_KEY_GEN)
			return PKCS11Constants.NAME_CKM_CAST_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_CAST_ECB)
			return PKCS11Constants.NAME_CKM_CAST_ECB;
		else if(algo == PKCS11Constants.CKM_CAST_CBC)
			return PKCS11Constants.NAME_CKM_CAST_CBC;
		else if(algo == PKCS11Constants.CKM_CAST_MAC)
			return PKCS11Constants.NAME_CKM_CAST_MAC;
		else if(algo == PKCS11Constants.CKM_CAST_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_CAST_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_CAST_CBC_PAD)
			return PKCS11Constants.NAME_CKM_CAST_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_CAST3_KEY_GEN)
			return PKCS11Constants.NAME_CKM_CAST3_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_CAST3_ECB)
			return PKCS11Constants.NAME_CKM_CAST3_ECB;
		else if(algo == PKCS11Constants.CKM_CAST3_CBC)
			return PKCS11Constants.NAME_CKM_CAST3_CBC;
		else if(algo == PKCS11Constants.CKM_CAST3_MAC)
			return PKCS11Constants.NAME_CKM_CAST3_MAC;
		else if(algo == PKCS11Constants.CKM_CAST3_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_CAST3_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_CAST3_CBC_PAD)
			return PKCS11Constants.NAME_CKM_CAST3_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_CAST5_KEY_GEN)
			return PKCS11Constants.NAME_CKM_CAST5_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_CAST128_KEY_GEN)
			return PKCS11Constants.NAME_CKM_CAST128_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_CAST5_ECB)
			return PKCS11Constants.NAME_CKM_CAST5_ECB;
		else if(algo == PKCS11Constants.CKM_CAST128_ECB)
			return PKCS11Constants.NAME_CKM_CAST128_ECB;
		else if(algo == PKCS11Constants.CKM_CAST5_CBC)
			return PKCS11Constants.NAME_CKM_CAST5_CBC;
		else if(algo == PKCS11Constants.CKM_CAST128_CBC)
			return PKCS11Constants.NAME_CKM_CAST128_CBC;
		else if(algo == PKCS11Constants.CKM_CAST5_MAC)
			return PKCS11Constants.NAME_CKM_CAST5_MAC;
		else if(algo == PKCS11Constants.CKM_CAST128_MAC)
			return PKCS11Constants.NAME_CKM_CAST128_MAC;
		else if(algo == PKCS11Constants.CKM_CAST5_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_CAST5_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_CAST128_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_CAST128_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_CAST5_CBC_PAD)
			return PKCS11Constants.NAME_CKM_CAST5_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_CAST128_CBC_PAD)
			return PKCS11Constants.NAME_CKM_CAST128_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_RC5_KEY_GEN)
			return PKCS11Constants.NAME_CKM_RC5_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_RC5_ECB)
			return PKCS11Constants.NAME_CKM_RC5_ECB;
		else if(algo == PKCS11Constants.CKM_RC5_CBC)
			return PKCS11Constants.NAME_CKM_RC5_CBC;
		else if(algo == PKCS11Constants.CKM_RC5_MAC)
			return PKCS11Constants.NAME_CKM_RC5_MAC;
		else if(algo == PKCS11Constants.CKM_RC5_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_RC5_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_RC5_CBC_PAD)
			return PKCS11Constants.NAME_CKM_RC5_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_IDEA_KEY_GEN)
			return PKCS11Constants.NAME_CKM_IDEA_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_IDEA_ECB)
			return PKCS11Constants.NAME_CKM_IDEA_ECB;
		else if(algo == PKCS11Constants.CKM_IDEA_CBC)
			return PKCS11Constants.NAME_CKM_IDEA_CBC;
		else if(algo == PKCS11Constants.CKM_IDEA_MAC)
			return PKCS11Constants.NAME_CKM_IDEA_MAC;
		else if(algo == PKCS11Constants.CKM_IDEA_MAC_GENERAL)
			return PKCS11Constants.NAME_CKM_IDEA_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_IDEA_CBC_PAD)
			return PKCS11Constants.NAME_CKM_IDEA_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_GENERIC_SECRET_KEY_GEN)
			return PKCS11Constants.NAME_CKM_GENERIC_SECRET_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY)
			return PKCS11Constants.NAME_CKM_CONCATENATE_BASE_AND_KEY;
		else if(algo == PKCS11Constants.CKM_CONCATENATE_BASE_AND_DATA) 
			return PKCS11Constants.NAME_CKM_CONCATENATE_BASE_AND_DATA;
		else if(algo == PKCS11Constants.CKM_CONCATENATE_DATA_AND_BASE)
			return PKCS11Constants.NAME_CKM_CONCATENATE_DATA_AND_BASE;
		else if(algo == PKCS11Constants.CKM_XOR_BASE_AND_DATA) 
			return PKCS11Constants.NAME_CKM_XOR_BASE_AND_DATA;
		else if(algo == PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY) 
			return PKCS11Constants.NAME_CKM_EXTRACT_KEY_FROM_KEY;
		else if(algo == PKCS11Constants.CKM_SSL3_PRE_MASTER_KEY_GEN) 
			return PKCS11Constants.NAME_CKM_SSL3_PRE_MASTER_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_SSL3_MASTER_KEY_DERIVE) 
			return PKCS11Constants.NAME_CKM_SSL3_MASTER_KEY_DERIVE;
		else if(algo == PKCS11Constants.CKM_SSL3_KEY_AND_MAC_DERIVE) 
			return PKCS11Constants.NAME_CKM_SSL3_KEY_AND_MAC_DERIVE;
		else if(algo == PKCS11Constants.CKM_SSL3_MASTER_KEY_DERIVE_DH) 
			return PKCS11Constants.NAME_CKM_SSL3_MASTER_KEY_DERIVE_DH;
		else if(algo == PKCS11Constants.CKM_TLS_PRE_MASTER_KEY_GEN) 
			return PKCS11Constants.NAME_CKM_TLS_PRE_MASTER_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_TLS_MASTER_KEY_DERIVE) 
			return PKCS11Constants.NAME_CKM_TLS_MASTER_KEY_DERIVE;
		else if(algo == PKCS11Constants.CKM_TLS_KEY_AND_MAC_DERIVE) 
			return PKCS11Constants.NAME_CKM_TLS_KEY_AND_MAC_DERIVE;
		else if(algo == PKCS11Constants.CKM_TLS_MASTER_KEY_DERIVE_DH) 
			return PKCS11Constants.NAME_CKM_TLS_MASTER_KEY_DERIVE_DH;
		else if(algo == PKCS11Constants.CKM_SSL3_MD5_MAC) 
			return PKCS11Constants.NAME_CKM_SSL3_MD5_MAC;
		else if(algo == PKCS11Constants.CKM_SSL3_SHA1_MAC) 
			return PKCS11Constants.NAME_CKM_SSL3_SHA1_MAC;
		else if(algo == PKCS11Constants.CKM_MD5_KEY_DERIVATION) 
			return PKCS11Constants.NAME_CKM_MD5_KEY_DERIVATION;
		else if(algo == PKCS11Constants.CKM_MD2_KEY_DERIVATION) 
			return PKCS11Constants.NAME_CKM_MD2_KEY_DERIVATION;
		else if(algo == PKCS11Constants.CKM_SHA1_KEY_DERIVATION) 
			return PKCS11Constants.NAME_CKM_SHA1_KEY_DERIVATION;
		else if(algo == PKCS11Constants.CKM_PBE_MD2_DES_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_MD2_DES_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_MD5_DES_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_MD5_DES_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_MD5_CAST_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_MD5_CAST_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_MD5_CAST3_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_MD5_CAST3_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_MD5_CAST5_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_MD5_CAST5_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_MD5_CAST128_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_MD5_CAST128_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_CAST5_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_CAST5_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_CAST128_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_CAST128_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_RC4_128) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_RC4_128;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_RC4_40) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_RC4_40;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_DES3_EDE_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_DES3_EDE_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_DES2_EDE_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_DES2_EDE_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_RC2_128_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_RC2_128_CBC;
		else if(algo == PKCS11Constants.CKM_PBE_SHA1_RC2_40_CBC) 
			return PKCS11Constants.NAME_CKM_PBE_SHA1_RC2_40_CBC;
		else if(algo == PKCS11Constants.CKM_PKCS5_PBKD2) 
			return PKCS11Constants.NAME_CKM_PKCS5_PBKD2;
		else if(algo == PKCS11Constants.CKM_PBA_SHA1_WITH_SHA1_HMAC) 
			return PKCS11Constants.NAME_CKM_PBA_SHA1_WITH_SHA1_HMAC;
		else if(algo == PKCS11Constants.CKM_KEY_WRAP_LYNKS) 
			return PKCS11Constants.NAME_CKM_KEY_WRAP_LYNKS;
		else if(algo == PKCS11Constants.CKM_KEY_WRAP_SET_OAEP) 
			return PKCS11Constants.NAME_CKM_KEY_WRAP_SET_OAEP;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_KEY_GEN) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_ECB64) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_ECB64;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_CBC64) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_CBC64;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_OFB64) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_OFB64;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_CFB64) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_CFB64;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_CFB32) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_CFB32;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_CFB16) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_CFB16;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_CFB8) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_CFB8;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_WRAP) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_WRAP;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_PRIVATE_WRAP) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_PRIVATE_WRAP;
		else if(algo == PKCS11Constants.CKM_SKIPJACK_RELAYX) 
			return PKCS11Constants.NAME_CKM_SKIPJACK_RELAYX;
		else if(algo == PKCS11Constants.CKM_KEA_KEY_PAIR_GEN) 
			return PKCS11Constants.NAME_CKM_KEA_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_KEA_KEY_DERIVE) 
			return PKCS11Constants.NAME_CKM_KEA_KEY_DERIVE;
		else if(algo == PKCS11Constants.CKM_FORTEZZA_TIMESTAMP) 
			return PKCS11Constants.NAME_CKM_FORTEZZA_TIMESTAMP;
		else if(algo == PKCS11Constants.CKM_BATON_KEY_GEN) 
			return PKCS11Constants.NAME_CKM_BATON_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_BATON_ECB128) 
			return PKCS11Constants.NAME_CKM_BATON_ECB128;
		else if(algo == PKCS11Constants.CKM_BATON_ECB96) 
			return PKCS11Constants.NAME_CKM_BATON_ECB96;
		else if(algo == PKCS11Constants.CKM_BATON_CBC128) 
			return PKCS11Constants.NAME_CKM_BATON_CBC128;
		else if(algo == PKCS11Constants.CKM_BATON_COUNTER) 
			return PKCS11Constants.NAME_CKM_BATON_COUNTER;
		else if(algo == PKCS11Constants.CKM_BATON_SHUFFLE) 
			return PKCS11Constants.NAME_CKM_BATON_SHUFFLE;
		else if(algo == PKCS11Constants.CKM_BATON_WRAP) 
			return PKCS11Constants.NAME_CKM_BATON_WRAP;
		else if(algo == PKCS11Constants.CKM_ECDSA_KEY_PAIR_GEN) 
			return PKCS11Constants.NAME_CKM_ECDSA_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_EC_KEY_PAIR_GEN) 
			return PKCS11Constants.NAME_CKM_EC_KEY_PAIR_GEN;
		else if(algo == PKCS11Constants.CKM_ECDSA) 
			return PKCS11Constants.NAME_CKM_ECDSA;
		else if(algo == PKCS11Constants.CKM_ECDSA_SHA1) 
			return PKCS11Constants.NAME_CKM_ECDSA_SHA1;
		else if(algo == PKCS11Constants.CKM_ECDH1_DERIVE) 
			return PKCS11Constants.NAME_CKM_ECDH1_DERIVE;
		else if(algo == PKCS11Constants.CKM_ECDH1_COFACTOR_DERIVE) 
			return PKCS11Constants.NAME_CKM_ECDH1_COFACTOR_DERIVE;
		else if(algo == PKCS11Constants.CKM_ECMQV_DERIVE) 
			return PKCS11Constants.NAME_CKM_ECMQV_DERIVE;
		else if(algo == PKCS11Constants.CKM_JUNIPER_KEY_GEN) 
			return PKCS11Constants.NAME_CKM_JUNIPER_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_JUNIPER_ECB128) 
			return PKCS11Constants.NAME_CKM_JUNIPER_ECB128;
		else if(algo == PKCS11Constants.CKM_JUNIPER_CBC128) 
			return PKCS11Constants.NAME_CKM_JUNIPER_CBC128;
		else if(algo == PKCS11Constants.CKM_JUNIPER_COUNTER) 
			return PKCS11Constants.NAME_CKM_JUNIPER_COUNTER;
		else if(algo == PKCS11Constants.CKM_JUNIPER_SHUFFLE) 
			return PKCS11Constants.NAME_CKM_JUNIPER_SHUFFLE;
		else if(algo == PKCS11Constants.CKM_JUNIPER_WRAP) 
			return PKCS11Constants.NAME_CKM_JUNIPER_WRAP;
		else if(algo == PKCS11Constants.CKM_FASTHASH) 
			return PKCS11Constants.NAME_CKM_FASTHASH;
		else if(algo == PKCS11Constants.CKM_AES_KEY_GEN) 
			return PKCS11Constants.NAME_CKM_AES_KEY_GEN;
		else if(algo == PKCS11Constants.CKM_AES_ECB) 
			return PKCS11Constants.NAME_CKM_AES_ECB;
		else if(algo == PKCS11Constants.CKM_AES_CBC) 
			return PKCS11Constants.NAME_CKM_AES_CBC;
		else if(algo == PKCS11Constants.CKM_AES_MAC) 
			return PKCS11Constants.NAME_CKM_AES_MAC;
		else if(algo == PKCS11Constants.CKM_AES_MAC_GENERAL) 
			return PKCS11Constants.NAME_CKM_AES_MAC_GENERAL;
		else if(algo == PKCS11Constants.CKM_AES_CBC_PAD) 
			return PKCS11Constants.NAME_CKM_AES_CBC_PAD;
		else if(algo == PKCS11Constants.CKM_DSA_PARAMETER_GEN) 
			return PKCS11Constants.NAME_CKM_DSA_PARAMETER_GEN;
		else if(algo == PKCS11Constants.CKM_DH_PKCS_PARAMETER_GEN) 
			return PKCS11Constants.NAME_CKM_DH_PKCS_PARAMETER_GEN;
		else if(algo == PKCS11Constants.CKM_X9_42_DH_PARAMETER_GEN) 
			return PKCS11Constants.NAME_CKM_X9_42_DH_PARAMETER_GEN;
		else if(algo == PKCS11Constants.CKM_VENDOR_DEFINED) 
			return PKCS11Constants.NAME_CKM_VENDOR_DEFINED;

		//Constante absente de iaki
		if(algo == 336L) return "CKM_DES_OFB64";
		else if(algo == 337L) 
			return "CKM_DES_OFB8";
		else if(algo == 338L) 
			return "CKM_DES_CFB64";
		else if(algo == 339L) 
			return "CKM_DES_CFB8";
		else if(algo == 592L) 
			return "CKM_SHA256";
		else if(algo == 593L) 
			return "CKM_SHA256_HMAC";
		else if(algo == 594L) 
			return "CKM_SHA256_HMAC_GENERAL";
		else if(algo == 608L) 
			return "CKM_SHA384";
		else if(algo == 609L) 
			return "CKM_SHA384_HMAC";
		else if(algo == 610L) 
			return "CKM_SHA384_HMAC_GENERAL";
		else if(algo == 624L) 
			return "CKM_SHA512";
		else if(algo == 625L) 
			return "CKM_SHA512_HMAC";
		else if(algo == 626L) 
			return "CKM_SHA512_HMAC_GENERAL";
		else if(algo == 888L) 
			return "CKM_TLS_PRF";
		else if(algo == 915L) 
			return "CKM_SHA256_KEY_DERIVATION";
		else if(algo == 916L) 
			return "CKM_SHA384_KEY_DERIVATION";
		else if(algo == 917L) 
			return "CKM_SHA512_KEY_DERIVATION";
		else if(algo == 976L) 
			return "CKM_WTLS_PRE_MASTER_KEY_GEN";
		else if(algo == 977L) 
			return "CKM_WTLS_MASTER_KEY_DERIVE";
		else if(algo == 978L) 
			return "CKM_WTLS_MASTER_KEY_DERVIE_DH_ECC";
		else if(algo == 979L) 
			return "CKM_WTLS_PRF";
		else if(algo == 980L) 
			return "CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE";
		else if(algo == 981L) 
			return "CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE";
		else if(algo == 1280L) 
			return "CKM_CMS_SIG";
		else if(algo == 64L) 
			return "CKM_SHA256_RSA_PKCS";
		else if(algo == 65L) 
			return "CKM_SHA384_RSA_PKCS";
		else if(algo == 66L) 
			return "CKM_SHA512_RSA_PKCS";
		else if(algo == 67L) 
			return "CKM_SHA256_RSA_PKCS_PSS";
		else if(algo == 68L) 
			return "CKM_SHA384_RSA_PKCS_PSS";
		else if(algo == 69L) 
			return "CKM_SHA512_RSA_PKCS_PSS";
		else if(algo == 4240L) 
			return "CKM_BLOWFISH_KEY_GEN";
		else if(algo == 4241L) 
			return "CKM_BLOWFISH_CBC";
		else if(algo == 4242L) 
			return "CKM_TWOFISH_KEY_GEN";
		else if(algo == 4243L) 
			return "CKM_TWOFISH_CBC";
		else if(algo == 4352L) 
			return "CKM_DES_ECB_ENCRYPT_DATA";
		else if(algo == 4353L) 
			return "CKM_DES_CBC_ENCRYPT_DATA";
		else if(algo == 4354L) 
			return "CKM_DES3_ECB_ENCRYPT_DATA";
		else if(algo == 4355L) 
			return "CKM_DES3_CBC_ENCRYPT_DATA";
		else if(algo == 4356L) 
			return "CKM_AES_ECB_ENCRYPT_DATA";
		else if(algo == 4357L) 
			return "CKM_AES_CBC_ENCRYPT_DATA";
	
		return Long.toString(algo);
	}	
	


	/**
	 * Retourne une représentation sous forme de chaîne de caractère du type de clé
	 * @param type Type de clé sous forme de long
 	 */
	public static String getNomTypeCle(long type) {
		
		String s = "inconnu";
		
		if(type == PKCS11Constants.CKK_AES)
			s = new String("CKK_AES");
		else if(type == PKCS11Constants.CKK_BATON)
			s = new String("CKK_BATON");
		else if(type == PKCS11Constants.CKK_CAST)
			s = new String("CKK_CAST");
		else if(type == PKCS11Constants.CKK_CAST128)
			s = new String("CKK_CAST128");
		else if(type == PKCS11Constants.CKK_CAST3)
			s = new String("CKK_CAST3");
		else if(type == PKCS11Constants.CKK_CAST5)
			s = new String("CKK_CAST5");
		else if(type == PKCS11Constants.CKK_CDMF)
			s = new String("CKK_CDMF");
		else if(type == PKCS11Constants.CKK_DES)
			s = new String("CKK_DES");
		else if(type == PKCS11Constants.CKK_DES2) 
			s = new String("CKK_DES2");
		else if(type == PKCS11Constants.CKK_DES3)
			s = new String("CKK_DES3");
		else if(type == PKCS11Constants.CKK_DH)
			s = new String("CKK_DH");
		else if(type == PKCS11Constants.CKK_DSA) 
			s = new String("CKK_DSA");
		else if(type == PKCS11Constants.CKK_EC)
			s = new String("CKK_EC");
		else if(type == PKCS11Constants.CKK_ECDSA)
			s = new String("CKK_ECDSA");
		else if(type == PKCS11Constants.CKK_GENERIC_SECRET)
			s = new String("CKK_GENERIC_SECRET");
		else if(type == PKCS11Constants.CKK_IDEA)
			s = new String("CKK_IDEA");
		else if(type == PKCS11Constants.CKK_JUNIPER)
			s = new String("CKK_JUNIPER");
		else if(type == PKCS11Constants.CKK_KEA)
			s = new String("CKK_KEA");
		else if(type == PKCS11Constants.CKK_RC2)
			s = new String("CKK_RC2");
		else if(type == PKCS11Constants.CKK_RC4)
			s = new String("CKK_RC4");
		else if(type == PKCS11Constants.CKK_RC5)
			s = new String("CKK_RC5");
		else if(type == PKCS11Constants.CKK_RSA)
			s = new String("CKK_RSA");
		else if(type == PKCS11Constants.CKK_SKIPJACK)
			s = new String("CKK_SKIPJACK");
		else if(type == PKCS11Constants.CKK_VENDOR_DEFINED)
			s = new String("CKK_VENDOR_DEFINED");
		else if(type == PKCS11Constants.CKK_X9_42_DH)
			s = new String("CKK_X9_42_DH");

		return s;
	}

	
	/**
	 * Retranscrit le Code retour PKCS#11
	 * @return libellé associé au code retour
	 */
	public static String retranscritCodeRetour(long code) {

		String codeRetour = (code == AUCUN_CODE_RETOUR)?"":"0x" + Functions.toFullHexString((int)code);
		
		if(codeRetour != null) {
			if(codeRetour.equalsIgnoreCase("0x00000000") || codeRetour.equalsIgnoreCase("CKR_OK") ) return "CKR_OK (0x00000000)";
			else if(codeRetour.equalsIgnoreCase("0x00000001")) return "CKR_CANCEL ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000002")) return "CKR_HOST_MEMORY ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000003")) return "CKR_SLOT_ID_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000005")) return "CKR_GENERAL_ERROR ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000006")) return "CKR_FUNCTION_FAILED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000007")) return "CKR_ARGUMENTS_BAD ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000008")) return "CKR_NO_EVENT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000009")) return "CKR_NEED_TO_CREATE_THREADS ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x0000000A")) return "CKR_CANT_LOCK ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000010")) return "CKR_ATTRIBUTE_READ_ONLY ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000011")) return "CKR_ATTRIBUTE_SENSITIVE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000012")) return "CKR_ATTRIBUTE_TYPE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000013")) return "CKR_ATTRIBUTE_VALUE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000020")) return "CKR_DATA_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000021")) return "CKR_DATA_LEN_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000030")) return "CKR_DEVICE_ERROR ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000031")) return "CKR_DEVICE_MEMORY ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000032")) return "CKR_DEVICE_REMOVED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000040")) return "CKR_ENCRYPTED_DATA_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000041")) return "CKR_ENCRYPTED_DATA_LEN_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000050")) return "CKR_FUNCTION_CANCELED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000051")) return "CKR_FUNCTION_NOT_PARALLEL ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000054")) return "CKR_FUNCTION_NOT_SUPPORTED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000060")) return "CKR_KEY_HANDLE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000062")) return "CKR_KEY_SIZE_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000063")) return "CKR_KEY_TYPE_INCONSISTENT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000064")) return "CKR_KEY_NOT_NEEDED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000065")) return "CKR_KEY_CHANGED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000066")) return "CKR_KEY_NEEDED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000067")) return "CKR_KEY_INDIGESTIBLE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000068")) return "CKR_KEY_FUNCTION_NOT_PERMITTED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000069")) return "CKR_KEY_NOT_WRAPPABLE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x0000006A")) return "CKR_KEY_UNEXTRACTABLE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000070")) return "CKR_MECHANISM_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000071")) return "CKR_MECHANISM_PARAM_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000082")) return "CKR_OBJECT_HANDLE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000090")) return "CKR_OPERATION_ACTIVE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000091")) return "CKR_OPERATION_NOT_INITIALIZED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000A0")) return "CKR_PIN_INCORRECT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000A1")) return "CKR_PIN_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000A2")) return "CKR_PIN_LEN_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000A3")) return "CKR_PIN_EXPIRED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000A4")) return "CKR_PIN_LOCKED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B0")) return "CKR_SESSION_CLOSED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B1")) return "CKR_SESSION_COUNT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B3")) return "CKR_SESSION_HANDLE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B4")) return "CKR_SESSION_PARALLEL_NOT_SUPPORTED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B5")) return "CKR_SESSION_READ_ONLY ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B6")) return "CKR_SESSION_EXISTS ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B7")) return "CKR_SESSION_READ_ONLY_EXISTS ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000B8")) return "CKR_SESSION_READ_WRITE_SO_EXISTS ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000C0")) return "CKR_SIGNATURE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000C1")) return "CKR_SIGNATURE_LEN_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000D0")) return "CKR_TEMPLATE_INCOMPLETE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000D1")) return "CKR_TEMPLATE_INCONSISTENT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000E0")) return "CKR_TOKEN_NOT_PRESENT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000E1")) return "CKR_TOKEN_NOT_RECOGNIZED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000E2")) return "CKR_TOKEN_WRITE_PROTECTED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000F0")) return "CKR_UNWRAPPING_KEY_HANDLE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000F1")) return "CKR_UNWRAPPING_KEY_SIZE_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000000F2")) return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000100")) return "CKR_USER_ALREADY_LOGGED_IN ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000101")) return "CKR_USER_NOT_LOGGED_IN ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000102")) return "CKR_USER_PIN_NOT_INITIALIZED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000103")) return "CKR_USER_TYPE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000104")) return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000105")) return "CKR_USER_TOO_MANY_TYPES ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000110")) return "CKR_WRAPPED_KEY_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000112")) return "CKR_WRAPPED_KEY_LEN_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000113")) return "CKR_WRAPPING_KEY_HANDLE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000114")) return "CKR_WRAPPING_KEY_SIZE_RANGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000115")) return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000120")) return "CKR_RANDOM_SEED_NOT_SUPPORTED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000121")) return "CKR_RANDOM_NO_RNG ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000130")) return "CKR_DOMAIN_PARAMS_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000150")) return "CKR_BUFFER_TOO_SMALL ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000160")) return "CKR_SAVED_STATE_INVALID ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000170")) return "CKR_INFORMATION_SENSITIVE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000180")) return "CKR_STATE_UNSAVEABLE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000190")) return "CKR_CRYPTOKI_NOT_INITIALIZED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000191")) return "CKR_CRYPTOKI_ALREADY_INITIALIZED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000001A0")) return "CKR_MUTEX_BAD ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x000001A1")) return "CKR_MUTEX_NOT_LOCKED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x00000200")) return "CKR_FUNCTION_REJECTED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000000")) return "CKR_VENDOR_DEFINED ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000001")) return "Erreur inattendue ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000002")) return "Librairie non chargée ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000003")) return "Liste des fonctions PKCS#11 indisponible ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000004")) return "Liste des fonctions PKCS#11 non initialisée ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000005")) return "Aucun lecteur présent ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000006")) return "Aucune carte supportée ("+codeRetour+")";
			//else if(codeRetour.equalsIgnoreCase("0x80000007")) return "Utilisateur authentifié ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000008")) return "Utilisateur non authentifié ("+codeRetour+")";	
			else if(codeRetour.equalsIgnoreCase("0x80000009")) return "Interruption utilisateur ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000010")) return "Code porteur invalide ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000011")) return "La longueur du code porteur est invalide ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000012")) return "CKR_DEMANDE_RECYCLAGE ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000013")) return "Echec de la mémorisation des cartes connectées ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000014")) return "La carte a été retrouvée ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000015")) return "Carte recherchée introuvable ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000016")) return "Opération non conforme ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000017")) return "Objet recherché introuvable ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000018")) return "Objet recherché trouvé mais non modifiable ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000019")) return "Aucun objet à modifier ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000020")) return "Utilisateur non authentifié (mode sans contact) ("+codeRetour+")";
			else if(codeRetour.equalsIgnoreCase("0x80000021")) return "Traitement non supporté en mode sans contact ("+codeRetour+")";
			else if(codeRetour.length() == 0) return "";
		}
		return null;
	}	

	/**
	 * Retranscrit le Flag PKCS#11
	 * @return libellé associé au flag
	 */
	public static String retranscritFlag(long flag) {

	    String flagHexString = "0x" + Functions.toFullHexString((int)flag);
		
		if(flagHexString.equalsIgnoreCase("0x80000001")) return "Aucun code erroné saisi sur cette carte !";
		else if(flagHexString.equalsIgnoreCase("0x80000002")) return "Attention un ou plusieurs codes porteurs erronés ont déjà été saisis sur cette carte !";
		else if(flagHexString.equalsIgnoreCase("0x80000003")) return "Attention dernière tentative avant blocage du code porteur !";
		else if(flagHexString.equalsIgnoreCase("0x80000004")) return "Code porteur bloqué !";
		else if(flagHexString.equalsIgnoreCase("0x80000005")) return "Vous disposez de 3 essais pour saisir le bon code porteur";
		else if(flagHexString.equalsIgnoreCase("0x80000006")) return "Attention 2 essais restants !";	
		else if(flagHexString.equalsIgnoreCase("0x80000007")) return "Attention 1 essai restant !";
		else if(flagHexString.equalsIgnoreCase("0x80000008")) return "Aucun code de déblocage erroné saisi sur cette carte !";
		else if(flagHexString.equalsIgnoreCase("0x80000009")) return "Attention un ou plusieurs codes de déblocage erronés ont déjà été saisis sur cette carte !";
		else if(flagHexString.equalsIgnoreCase("0x80000010")) return "Attention dernière tentative avant blocage du code de déblocage de la carte !";
		else if(flagHexString.equalsIgnoreCase("0x80000011")) return "Code de déblocage bloquée !";
		else if(flagHexString.equalsIgnoreCase("0x80000012")) return null;
		else if(flagHexString.equalsIgnoreCase("0x80000013")) return "La longueur du code porteur saisi est non conforme !";	
		else if(flagHexString.equalsIgnoreCase("0x80000014")) return "Le code porteur saisi est non conforme !";
		else if(flagHexString.equalsIgnoreCase("0x80000015")) return "Code porteur incorrect !";
		else if(flagHexString.equalsIgnoreCase("0x80000016")) return null;
		else if(flagHexString.equalsIgnoreCase("0x80000017")) return "La longueur du code de déblocage saisi est non conforme !";	
		else if(flagHexString.equalsIgnoreCase("0x80000018")) return "Le code de déblocage saisi est non conforme !";
		else if(flagHexString.equalsIgnoreCase("0x80000019")) return "Code de déblocage incorrect !";
		else if(flagHexString.equalsIgnoreCase("0x80000020")) return "Les nouveaux codes porteurs diffèrent !";		
		
		return null;
	}
	
	/**
	 * Retranscrit le couleur du flag
	 * @return couleur associé au flag
	 */
	public static Color retranscritCouleurFlag(long flag) {

	    String flagHexString = "0x" + Functions.toFullHexString((int)flag);
		
		if(flagHexString.equalsIgnoreCase("0x80000001")) return SaisieCodeNbEssais.NIVEAU_OK;
		else if(flagHexString.equalsIgnoreCase("0x80000002")) return SaisieCodeNbEssais.NIVEAU_ATTENTION;
		else if(flagHexString.equalsIgnoreCase("0x80000003")) return SaisieCodeNbEssais.NIVEAU_CRITIQUE;
		else if(flagHexString.equalsIgnoreCase("0x80000004")) return SaisieCodeNbEssais.NIVEAU_KO;
		else if(flagHexString.equalsIgnoreCase("0x80000005")) return SaisieCodeNbEssais.NIVEAU_OK;
		else if(flagHexString.equalsIgnoreCase("0x80000006")) return SaisieCodeNbEssais.NIVEAU_ATTENTION;	
		else if(flagHexString.equalsIgnoreCase("0x80000007")) return SaisieCodeNbEssais.NIVEAU_CRITIQUE;
		else if(flagHexString.equalsIgnoreCase("0x80000008")) return SaisieRecyclage.NIVEAU_OK;
		else if(flagHexString.equalsIgnoreCase("0x80000009")) return SaisieRecyclage.NIVEAU_ATTENTION;
		else if(flagHexString.equalsIgnoreCase("0x80000010")) return SaisieRecyclage.NIVEAU_CRITIQUE;
		
		
		return null;
	}	
	
	/**
	 * Recherche un ensemble de type d'objets
	 * @param application Instance de l'application cliente de la recherche
	 * @param type Type d'objet
	 * @param filtre Filtre de recherche (optionnel)
	 * @param afficheResultat Spécifie s'il faut afficher le résultat de la recherche à l'écran
	 * @return Resultat comprendre les objets trouvés
	 * @throws ExceptionProgrammeExemple
	 */
	public static Resultat rechercheObjets(Application application, int type, String filtre, boolean afficheResultat) throws ExceptionProgrammeExemple {
		
		Resultat resultat = null;
		if(application.getSessionCourante() != null) {
			
			Vector<Object> objets = new Vector<Object>();
			
			// On met d'abord à jour la liste des objets précédemment présents si nécessaire
			if(type == TraitementsUtil.TYPE_OBJET_DONNEES_APPLICATIVES
					&& application.getFiltresObjets() != null
						&& application.getFiltresObjets().size() > 0) {
				
				for (Iterator<String> iterator = application.getFiltresObjets().iterator(); iterator.hasNext();) {
					String f = iterator.next();
					Resultat res = RechercheObjets.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(), type, f);
					if(res != null && res.getCodeRetourStr() != null && res.getCodeRetourStr().startsWith("CKR_OK"))
						if(application.getSessionCourante() != null && application.getSessionCourante().getIdToken() != null) {
							for (Iterator<Object> iterator2 = res.getObjets().iterator(); iterator2.hasNext();) {
								Object obj = iterator2.next();
								if(!objets.contains(res.getObjets()))
									objets.add(obj);
							}
						}
				}
			}

			resultat = RechercheObjets.traitementP11(application.getLibrairieP11(), application.getSessionCourante().getIdSession(), type, filtre);
			
			// Déclenchement de l'affichage
			if(resultat != null && afficheResultat)
				application.declencheAffichageResultat(resultat);
			
			if(resultat != null && resultat.getCodeRetourStr() != null && resultat.getCodeRetourStr().startsWith("CKR_OK")) {
				if(application.getSessionCourante() != null && application.getSessionCourante().getIdToken() != null) {

					application.ajouteFiltreObjet(filtre);
					
					// On remet à zéro
					application.supprimeTousLesObjetsDeType(application.getSessionCourante().getIdToken(), type);
					
					objets.addAll(resultat.getObjets());
					
					// puis on ajoute
					application.ajouteLesObjets(application.getLibrairieP11(),application.getSessionCourante(), application.getSessionCourante().getIdToken(),objets,type);
					
				}
			}
			
		} else {
			log.error("Une erreur inattendue est survenue lors de la tentative d'execution de l'operation de recherche de l'objet : Il n'y a pas de session en cours");
			application.notifieException(new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_OBJETS_RECHERCHE,"Une erreur inattendue est survenue"));
		}
		return resultat;
	}
}
